package com.ctgu.rabbitmq.service.impl;

import com.ctgu.rabbitmq.entity.OrdersEntity;
import com.ctgu.rabbitmq.mapper.OrdersMapper;
import com.ctgu.rabbitmq.rabbitmq.delayQueue.deadLetterDelayQueue.DeadLetterDelayQueueConfig;
import com.ctgu.rabbitmq.rabbitmq.delayQueue.delayPlugin.DelayPluginConfig;
import com.ctgu.rabbitmq.service.DelayQueueService;
import com.ctgu.rabbitmq.utils.ApiResult;
import lombok.extern.log4j.Log4j2;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

/**
 * @ ClassName DelayServiceImpl
 * @ Author Alex2
 * @ Date 2025/8/15 14:57
 **/
@Log4j2
@Service
public class DelayQueueServiceImpl implements DelayQueueService {

    private static final String TAG = "Alex";

    private final OrdersMapper ordersMapper;
    private final RabbitTemplate rabbitTemplate;

    public DelayQueueServiceImpl(OrdersMapper ordersMapper, RabbitTemplate rabbitTemplate) {
        this.ordersMapper = ordersMapper;
        this.rabbitTemplate = rabbitTemplate;
    }

    /**
     * @ Author: Alex
     * @ Description: 延迟队列-定时任务
     */
    // @Scheduled(fixedRate = 60 * 1000)   // 每分钟检查一次
    public void closeTimeoutOrders() {
        LocalDateTime cutoffTime = LocalDateTime.now().minusMinutes(10);
        List<OrdersEntity> ordersToClose = ordersMapper.findUnpaidOrdersBefore(cutoffTime);
        for (OrdersEntity ordersEntity : ordersToClose) {
            ordersEntity.setStatus("CLOSED");
            ordersMapper.updateById(ordersEntity);
            log.debug("{} : 订单 : {} : 超时关闭", TAG, ordersEntity.getId());
        }
    }

    /**
     * @ Author: Alex
     * @ Description: 延迟队列-死信队列实现延迟队列
     */
    public ApiResult deadLetterDelayQueue(String name, BigDecimal price, Integer userId) {
        OrdersEntity existingOrder = ordersMapper.selectByName(name);
        if (existingOrder != null) {
            log.debug("{} : 订单插入失败，该订单已存在 : orderId = {}", TAG, existingOrder.getId());
            return ApiResult.error("订单已存在");
        }
        OrdersEntity ordersEntity = new OrdersEntity(null, name, price, userId, "UNPAID", LocalDateTime.now());
        ordersMapper.insert(ordersEntity);
        rabbitTemplate.convertAndSend(      // 发送到普通交换机，10分钟后进入死信队列
                DeadLetterDelayQueueConfig.NORMAL_EXCHANGE_DELAY_QUEUE,
                DeadLetterDelayQueueConfig.NORMAL_ROUTING_KEY_DELAY_QUEUE,
                ordersEntity.getId()
        );
        log.debug("{} : 下单成功，订单ID={} 已发送延迟关单消息", TAG, ordersEntity.getId());
        return ApiResult.success("下单成功");
    }

    /**
     * @ Author: Alex
     * @ Description: 延迟插件实现延迟队列
     */
    @Override
    public ApiResult delayPlugin(String name, BigDecimal price, Integer userId) {
        OrdersEntity existingOrder = ordersMapper.selectByName(name);
        if (existingOrder != null) {
            return ApiResult.error("订单已存在");
        }

        OrdersEntity ordersEntity = new OrdersEntity(null, name, price, userId, "UNPAID", LocalDateTime.now());
        ordersMapper.insert(ordersEntity);
        rabbitTemplate.convertAndSend(
                DelayPluginConfig.DLX_EXCHANGE_DELAY_PLUGIN,
                DelayPluginConfig.DLX_ROUTING_KEY_DELAY_PLUGIN,
                ordersEntity.getId(),
                message -> {
                    message.getMessageProperties().setDelay(10 * 60 * 1000);        // 设置延迟时间：10分钟
                    return message;
                }
        );
        log.debug("下单成功，订单ID={} 已发送延迟关单消息", ordersEntity.getId());
        return ApiResult.success("下单成功");
    }
}